
#ifndef WGDALRASTER_H

#define WGDALRASTER_H

#include "gdal_priv.h"
#include <string>
#include <vector>
#include <iostream>
using std::vector ;
using std::string;
using std::cout;
using std::endl;


enum wGdalRasterState
{
	wGdalRasterStateNone ,
	wGdalRasterStateOpen , 
	wGdalRasterStateCreate 
} ;

class wGdalRaster
{
public:
	int getXSize() ;
	int getYSize() ;
	int getNBand() ;

	virtual float getValuef(int ix,int iy,int ib ) =0;
	virtual float getValuef(int it ,int ib ) =0;
	virtual int getValuei(int ix,int iy,int ib )=0 ;
	virtual int getValuei(int it , int ib  ) =0;

	virtual void setValuef(int ix,int iy,int ib,float val)=0 ;
	virtual void setValuei(int ix,int iy,int ib,int val) =0;
	virtual void setValuef(int it,int ib,float val) =0;
	virtual void setValuei(int it,int ib,int val) =0;

	virtual bool open(string filepath)=0 ;
	virtual bool save(string filepath)=0 ;
	virtual bool create(int nxsize,int nysize,int nband )=0 ;
 
	virtual void fill(int iband,int fillval) =0;

	wGdalRaster() ;
	wGdalRasterState getState() ;
	virtual ~wGdalRaster() ;

	void copyProj( const char* projstr ) ;
	void copyTrans(double* trans ) ;
	char* getProj() ;
	double* getTrans() ;
	
protected:
	wGdalRasterState mState ;
	int mXSize , mYSize , mNBand ;
	char mProj[1024] ;
	double mTrans[6] ;
} ;

 

wGdalRaster::~wGdalRaster()
{
}

wGdalRaster::wGdalRaster()
{
	mXSize = 0 ;
	mYSize = 0 ; 
	mNBand = 0 ;
	mProj[0]='\0' ;
	mTrans[0] = mTrans[1] = mTrans[2] = mTrans[3] = mTrans[4] = mTrans[5] = 0 ;
	mState = wGdalRasterStateNone ;
}

void wGdalRaster::copyProj(const char* projstr ) 
{
	strcpy( this->mProj , projstr ) ;
}
void  wGdalRaster::copyTrans(double* trans ) 
{
	for(int i = 0 ; i<6 ; ++i ) mTrans[i] = trans[i] ;
}
char* wGdalRaster::getProj() 
{
	return mProj ;
}
double* wGdalRaster::getTrans() 
{
	return mTrans ;
}

wGdalRasterState wGdalRaster::getState()
{
	return mState ;
} 
int wGdalRaster::getXSize()
{
	return mXSize ;
}

int wGdalRaster::getYSize()
{
	return mYSize ;
}

int wGdalRaster::getNBand()
{
	return mNBand ;
}
 




////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
//                                       BYTE
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////


class wGdalRasterByte:public wGdalRaster
{
public:
	virtual float getValuef(int ix,int iy,int ib ) ;
	virtual float getValuef(int it ,int ib )  ;
	virtual int getValuei(int ix,int iy,int ib )  ;
	virtual int getValuei(int it , int ib  )  ;

	virtual void setValuef(int ix,int iy,int ib,float val)  ;
	virtual void setValuei(int ix,int iy,int ib,int val)    ;
	virtual void setValuef(int it,int ib,float val)  ;
	virtual void setValuei(int it,int ib,int val) ;

	virtual bool open(string filepath)  ;
	virtual bool save(string filepath)  ;
	virtual bool create(int nxsize,int nysize,int nband )  ;

	//new
	virtual void fill(int iband,int fillval) ;


	void release() ;
	virtual ~wGdalRasterByte() ;
    
    bool save(string filepath, int nodata) ;//added 2020-11-19
protected:
	vector<unsigned char*> mptrVec ;
} ;

//new
void wGdalRasterByte::fill( int iband , int fillval )
{
	if( this->mState == wGdalRasterStateOpen ||  this->mState == wGdalRasterStateCreate )
	{
		if( iband < this->mptrVec.size() )
		{
			unsigned char* bandPtr = (unsigned char*)this->mptrVec[iband] ;
			int asize = this->mXSize * this->mYSize ;
			for(int it = 0 ; it < asize ; ++ it )
			{
				bandPtr[it] = fillval ;
			}
		}else
		{
			cout<<"wGdalRaster::fill error 1."<<endl ;
		}
	}else
	{
		cout<<"wGdalRaster::fill error 2."<<endl ;
	}
}

wGdalRasterByte::~wGdalRasterByte()
{
	this->release() ;
}
void wGdalRasterByte::release()
{
	cout<<"release byte"<<endl ;
	this->mState = wGdalRasterStateNone ;
	for(int i = 0 ; i<mptrVec.size() ; ++ i )
	{
		if( mptrVec[i] )
		{
			delete[] mptrVec[i] ;
			mptrVec[i] = 0 ;
		}
	}
}
float wGdalRasterByte::getValuef(int ix,int iy,int ib ) 
{
	unsigned char* ptr = mptrVec[ib] ;
	return (float)( ptr[ix+iy*mXSize] ) ;
}
float wGdalRasterByte::getValuef(int it ,int ib ) 
{
	unsigned char* ptr = mptrVec[ib] ;
	return (float)( ptr[it] ) ;
}
int wGdalRasterByte::getValuei(int ix,int iy,int ib ) 
{
	unsigned char* ptr = mptrVec[ib] ;
	return (int)( ptr[ix+iy*mXSize] ) ;
}
int wGdalRasterByte::getValuei(int it , int ib  ) 
{
	unsigned char* ptr = mptrVec[ib] ;
	return (int)( ptr[it] ) ;
}
void wGdalRasterByte::setValuef(int ix,int iy,int ib,float val)  
{
	unsigned char* ptr = mptrVec[ib] ;
	ptr[ix+iy*mXSize] = (int)val ;
}
void wGdalRasterByte::setValuei(int ix,int iy,int ib,int val)    
{
	unsigned char* ptr = mptrVec[ib] ;
	ptr[ix+iy*mXSize] = (int)val ;
}
void wGdalRasterByte::setValuef(int it,int ib,float val)  
{
	unsigned char* ptr = mptrVec[ib] ;
	ptr[it] = (int)val ;
}
void wGdalRasterByte::setValuei(int it,int ib,int val) 
{
	unsigned char* ptr = mptrVec[ib] ;
	ptr[it] = (int)val ;
}

bool wGdalRasterByte::open(string filepath) 
{
	if( this->mState != wGdalRasterStateNone)
	{
		return false ;
	}
	GDALDataset* ds = (GDALDataset*)GDALOpen( filepath.c_str() , GA_ReadOnly ) ;
	if( ds==0 )
	{
		return false ;
	}

	strcpy( mProj , ds->GetProjectionRef() ) ;
	ds->GetGeoTransform( mTrans ) ;

	mXSize = ds->GetRasterXSize() ;
	mYSize = ds->GetRasterYSize() ;
	mNBand = ds->GetRasterCount() ;

	for(int i = 0 ; i<mNBand ; ++ i )
	{
		unsigned char* ptr = new unsigned char[mXSize*mYSize] ;
		CPLErr ioerror = ds->GetRasterBand(i+1)->RasterIO( GF_Read ,
			0,0,mXSize,mYSize,
			ptr , 
			mXSize,mYSize,GDT_Byte , 
			0,0,0) ;
        if( ioerror != CE_None ){
            return false ;
        }
		mptrVec.push_back(ptr) ;
	}
	GDALClose(ds) ;
	this->mState = wGdalRasterStateOpen ;
	return true ;
}
bool wGdalRasterByte::save(string filepath) 
{
	if( this->mState == wGdalRasterStateNone)
	{
		return false   ;
	}
	string last3char = "" ;
	if( filepath.length() > 5 )
	{
		last3char = filepath.substr( filepath.length() - 3 , 3 ) ;
	}

	GDALDriver* driver = 0;
	if( last3char == "png" || last3char=="PNG" )
	{
		driver = GetGDALDriverManager()->GetDriverByName("MEM");
	}else
	{
		driver = GetGDALDriverManager()->GetDriverByName("GTiff");
	}

	GDALDataset* ds = driver->Create( filepath.c_str() , mXSize, mYSize , mNBand,GDT_Byte,0) ;
	if( ds==0 )
	{
		return false  ;
	}
	for(int i = 0 ; i<mNBand ; ++ i )
	{
		unsigned char* ptr = mptrVec[i] ;
		CPLErr ioerror = ds->GetRasterBand(i+1)->RasterIO( GF_Write,
			0,0,mXSize,mYSize,
			ptr , 
			mXSize,mYSize,GDT_Byte , 
			0,0,0) ;
        if( ioerror != CE_None ){
            return false ;
        }
	}
	if( strlen( mProj ) > 1 && mTrans[1] > 0 )
	{
		ds->SetProjection( mProj ) ;
		ds->SetGeoTransform( mTrans ) ;
	}
	

	if( last3char == "png" || last3char=="PNG" )
	{
		GDALDriver* driverpng = GetGDALDriverManager()->GetDriverByName("PNG");
		GDALDataset* dspng = driverpng->CreateCopy( filepath.c_str() , ds , 0 , 0 , 0 , 0 ) ;
		GDALClose(dspng) ;
	}

	GDALClose(ds) ;
	return true ;
}

bool wGdalRasterByte::save(string filepath, int nodata) 
{
	if( this->mState == wGdalRasterStateNone)
	{
		return false   ;
	}
	string last3char = "" ;
	if( filepath.length() > 5 )
	{
		last3char = filepath.substr( filepath.length() - 3 , 3 ) ;
	}

	GDALDriver* driver = 0;
	if( last3char == "png" || last3char=="PNG" )
	{
		driver = GetGDALDriverManager()->GetDriverByName("MEM");
	}else
	{
		driver = GetGDALDriverManager()->GetDriverByName("GTiff");
	}

	GDALDataset* ds = driver->Create( filepath.c_str() , mXSize, mYSize , mNBand,GDT_Byte,0) ;
	if( ds==0 )
	{
		return false  ;
	}
	for(int i = 0 ; i<mNBand ; ++ i )
	{
		unsigned char* ptr = mptrVec[i] ;
		CPLErr ioerror = ds->GetRasterBand(i+1)->RasterIO( GF_Write,
			0,0,mXSize,mYSize,
			ptr , 
			mXSize,mYSize,GDT_Byte , 
			0,0,0) ;
         if( ioerror != CE_None ){
            return false ;
        }
        ds->GetRasterBand(i+1)->SetNoDataValue(nodata) ;
	}
	if( strlen( mProj ) > 1 && mTrans[1] > 0 )
	{
		ds->SetProjection( mProj ) ;
		ds->SetGeoTransform( mTrans ) ;
        
	}
	

	if( last3char == "png" || last3char=="PNG" )
	{
		GDALDriver* driverpng = GetGDALDriverManager()->GetDriverByName("PNG");
		GDALDataset* dspng = driverpng->CreateCopy( filepath.c_str() , ds , 0 , 0 , 0 , 0 ) ;
		GDALClose(dspng) ;
	}

	GDALClose(ds) ;
	return true ;
}

bool wGdalRasterByte::create(int nxsize,int nysize,int nband ) 
{
	if( this->mState != wGdalRasterStateNone)
	{
		return false ;
	}
	mXSize = nxsize ;
	mYSize = nysize ;
	mNBand = nband ;
	for(int i = 0 ; i<mNBand ; ++ i )
	{
		unsigned char* ptr = new unsigned char[mXSize*mYSize] ;
		memset(ptr , 0 , mXSize*mYSize ) ;
		mptrVec.push_back(ptr) ;
	}
	this->mState = wGdalRasterStateCreate ;
	return true ;
}












////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
//                                       FLOAT
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
class wGdalRasterFloat:public wGdalRaster
{
public:
	virtual float getValuef(int ix,int iy,int ib ) ;
	virtual float getValuef(int it ,int ib )  ;
	virtual int getValuei(int ix,int iy,int ib )  ;
	virtual int getValuei(int it , int ib  )  ;

	virtual void setValuef(int ix,int iy,int ib,float val)  ;
	virtual void setValuei(int ix,int iy,int ib,int val)    ;
	virtual void setValuef(int it,int ib,float val)  ;
	virtual void setValuei(int it,int ib,int val) ;

	virtual bool open(string filepath)  ;
	virtual bool save(string filepath)  ;
	virtual bool create(int nxsize,int nysize,int nband )  ;

	//new
	virtual void fill(int iband,int fillval) ;


	void release() ;
	virtual ~wGdalRasterFloat() ;
protected:
	vector<float*> mptrVec ;
} ;


//new
void wGdalRasterFloat::fill( int iband , int fillval )
{
	if( this->mState == wGdalRasterStateOpen ||  this->mState == wGdalRasterStateCreate )
	{
		if( iband < this->mptrVec.size() )
		{
			float* bandPtr = (float*)this->mptrVec[iband] ;
			int asize = this->mXSize * this->mYSize ;
			for(int it = 0 ; it < asize ; ++ it )
			{
				bandPtr[it] = fillval ;
			}
		}else
		{
			cout<<"wGdalRaster::fill error 1."<<endl ;
		}
	}else
	{
		cout<<"wGdalRaster::fill error 2."<<endl ;
	}
}

wGdalRasterFloat::~wGdalRasterFloat() 
{
	this->release() ;
}

void wGdalRasterFloat::release()
{
	cout<<"release float"<<endl ;
	this->mState = wGdalRasterStateNone ;
	for(int i = 0 ; i<mptrVec.size() ; ++ i )
	{
		if( mptrVec[i] )
		{
			delete[] mptrVec[i] ;
			mptrVec[i] = 0 ;
		}
	}
}
float wGdalRasterFloat::getValuef(int ix,int iy,int ib ) 
{
	float* ptr = mptrVec[ib] ;
	return   ptr[ix+iy*mXSize]  ;
}
float wGdalRasterFloat::getValuef(int it ,int ib ) 
{
	float* ptr = mptrVec[ib] ;
	return   ptr[it]  ;
}
int wGdalRasterFloat::getValuei(int ix,int iy,int ib ) 
{
	float* ptr = mptrVec[ib] ;
	return (int)( ptr[ix+iy*mXSize] ) ;
}
int wGdalRasterFloat::getValuei(int it , int ib  ) 
{
	float* ptr = mptrVec[ib] ;
	return (int)( ptr[it] ) ;
}
void wGdalRasterFloat::setValuef(int ix,int iy,int ib,float val)  
{
	float* ptr = mptrVec[ib] ;
	ptr[ix+iy*mXSize] = val ;
}
void wGdalRasterFloat::setValuei(int ix,int iy,int ib,int val)    
{
	float* ptr = mptrVec[ib] ;
	ptr[ix+iy*mXSize] = val ;
}
void wGdalRasterFloat::setValuef(int it,int ib,float val)  
{
	float* ptr = mptrVec[ib] ;
	ptr[it] = val ;
}
void wGdalRasterFloat::setValuei(int it,int ib,int val) 
{
	float* ptr = mptrVec[ib] ;
	ptr[it] = val ;
}

bool wGdalRasterFloat::open(string filepath) 
{
	if( this->mState != wGdalRasterStateNone)
	{
		return false ;
	}
	GDALDataset* ds = (GDALDataset*)GDALOpen( filepath.c_str() , GA_ReadOnly ) ;
	if( ds==0 )
	{
		return false ;
	}

	strcpy( mProj , ds->GetProjectionRef() ) ;
	ds->GetGeoTransform( mTrans ) ;

	mXSize = ds->GetRasterXSize() ;
	mYSize = ds->GetRasterYSize() ;
	mNBand = ds->GetRasterCount() ;

	for(int i = 0 ; i<mNBand ; ++ i )
	{
		float* ptr = new float[mXSize*mYSize] ;
        CPLErr ioerror = ds->GetRasterBand(i+1)->RasterIO( GF_Read ,
			0,0,mXSize,mYSize,
			ptr , 
			mXSize,mYSize,GDT_Float32 , 
			0,0,0) ;
        if( ioerror != CE_None ){
            return false ;
        }
		mptrVec.push_back(ptr) ;
	}
	GDALClose(ds) ;
	this->mState = wGdalRasterStateOpen ;
	return true ;
}
bool wGdalRasterFloat::save(string filepath) 
{
	if( this->mState == wGdalRasterStateNone)
	{
		return false   ;
	}
	GDALDriver* driver = GetGDALDriverManager()->GetDriverByName("GTiff");
	GDALDataset* ds = driver->Create( filepath.c_str() , mXSize, mYSize , mNBand,GDT_Float32 ,0) ;
	if( ds==0 )
	{
		return false  ;
	}
	for(int i = 0 ; i<mNBand ; ++ i )
	{
		float* ptr = mptrVec[i] ;
		CPLErr ioerror = ds->GetRasterBand(i+1)->RasterIO( GF_Write,
			0,0,mXSize,mYSize,
			ptr , 
			mXSize,mYSize,GDT_Float32 , 
			0,0,0) ;
         if( ioerror != CE_None ){
            return false ;
        }
	}
	if( strlen( mProj ) > 1 && mTrans[1] > 0 )
	{
		ds->SetProjection( mProj ) ;
		ds->SetGeoTransform( mTrans ) ;
	}
	GDALClose(ds) ;
	return true ;
}
bool wGdalRasterFloat::create(int nxsize,int nysize,int nband ) 
{
	if( this->mState != wGdalRasterStateNone)
	{
		return false ;
	}
	mXSize = nxsize ;
	mYSize = nysize ;
	mNBand = nband ;
	int asize = mXSize*mYSize ;
	for(int i = 0 ; i<mNBand ; ++ i )
	{
		float* ptr = new float[mXSize*mYSize] ;
		for(int it = 0 ; it<asize;++it) ptr[it] = 0.f ;
		mptrVec.push_back(ptr) ;
	}
	this->mState = wGdalRasterStateCreate ;
	return true ;
}






////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
//                                       U16
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
class wGdalRasterU16:public wGdalRaster
{
public:
	virtual float getValuef(int ix,int iy,int ib ) ;
	virtual float getValuef(int it ,int ib )  ;
	virtual int getValuei(int ix,int iy,int ib )  ;
	virtual int getValuei(int it , int ib  )  ;

	virtual void setValuef(int ix,int iy,int ib,float val)  ;
	virtual void setValuei(int ix,int iy,int ib,int val)    ;
	virtual void setValuef(int it,int ib,float val)  ;
	virtual void setValuei(int it,int ib,int val) ;

	virtual bool open(string filepath)  ;
	virtual bool save(string filepath)  ;
	virtual bool create(int nxsize,int nysize,int nband )  ;
	void release() ;

	unsigned short getValueU16(int it,int ib) ;
	unsigned short getValueU16(int ix,int iy,int ib) ;

	//new
	virtual void fill(int iband,int fillval) ;

	virtual ~wGdalRasterU16() ;

protected:
	vector<unsigned short*> mptrVec ;
} ;


//new
void wGdalRasterU16::fill( int iband , int fillval )
{
	if( this->mState == wGdalRasterStateOpen ||  this->mState == wGdalRasterStateCreate )
	{
		if( iband < this->mptrVec.size() )
		{
			unsigned short* bandPtr = (unsigned short*)this->mptrVec[iband] ;
			int asize = this->mXSize * this->mYSize ;
			for(int it = 0 ; it < asize ; ++ it )
			{
				bandPtr[it] = fillval ;
			}
		}else
		{
			cout<<"wGdalRaster::fill error 1."<<endl ;
		}
	}else
	{
		cout<<"wGdalRaster::fill error 2."<<endl ;
	}
}

wGdalRasterU16::~wGdalRasterU16() 
{
	this->release() ;
}

void wGdalRasterU16::release()
{
	cout<<"release u16"<<endl ;
	this->mState = wGdalRasterStateNone ;
	for(int i = 0 ; i<mptrVec.size() ; ++ i )
	{
		if( mptrVec[i] )
		{
			delete[] mptrVec[i] ;
			mptrVec[i] = 0 ;
		}
	}
}
unsigned short wGdalRasterU16::getValueU16(int ix,int iy,int ib) 
{
	unsigned short* ptr = mptrVec[ib] ;
	return   ptr[ix+iy*mXSize]  ;
}

unsigned short wGdalRasterU16::getValueU16(int it,int ib) 
{
	unsigned short* ptr = mptrVec[ib] ;
	return   ptr[it]  ;
}


float wGdalRasterU16::getValuef(int ix,int iy,int ib ) 
{
	unsigned short* ptr = mptrVec[ib] ;
	return  (float) ptr[ix+iy*mXSize]  ;
}
float wGdalRasterU16::getValuef(int it ,int ib ) 
{
	unsigned short* ptr = mptrVec[ib] ;
	return  (float)ptr[it]  ;
}
int wGdalRasterU16::getValuei(int ix,int iy,int ib ) 
{
	unsigned short* ptr = mptrVec[ib] ;
	return (int)( ptr[ix+iy*mXSize] ) ;
}
int wGdalRasterU16::getValuei(int it , int ib  ) 
{
	unsigned short* ptr = mptrVec[ib] ;
	return (int)( ptr[it] ) ;
}
void wGdalRasterU16::setValuef(int ix,int iy,int ib,float val)  
{
	unsigned short*ptr = mptrVec[ib] ;
	ptr[ix+iy*mXSize] = val ;
}
void wGdalRasterU16::setValuei(int ix,int iy,int ib,int val)    
{
	unsigned short* ptr = mptrVec[ib] ;
	ptr[ix+iy*mXSize] = val ;
}
void wGdalRasterU16::setValuef(int it,int ib,float val)  
{
	unsigned short* ptr = mptrVec[ib] ;
	ptr[it] = val ;
}
void wGdalRasterU16::setValuei(int it,int ib,int val) 
{
	unsigned short* ptr = mptrVec[ib] ;
	ptr[it] = val ;
}

bool wGdalRasterU16::open(string filepath) 
{
	if( this->mState != wGdalRasterStateNone)
	{
		return false ;
	}
	GDALDataset* ds = (GDALDataset*)GDALOpen( filepath.c_str() , GA_ReadOnly ) ;
	if( ds==0 )
	{
		return false ;
	}

	strcpy( mProj , ds->GetProjectionRef() ) ;
	ds->GetGeoTransform( mTrans ) ;

	mXSize = ds->GetRasterXSize() ;
	mYSize = ds->GetRasterYSize() ;
	mNBand = ds->GetRasterCount() ;

	for(int i = 0 ; i<mNBand ; ++ i )
	{
		unsigned short* ptr = new unsigned short[mXSize*mYSize] ;
		CPLErr ioerror = ds->GetRasterBand(i+1)->RasterIO( GF_Read ,
			0,0,mXSize,mYSize,
			ptr , 
			mXSize,mYSize,GDT_UInt16 , 
			0,0,0) ;
         if( ioerror != CE_None ){
            return false ;
        }
		mptrVec.push_back(ptr) ;
	}
	GDALClose(ds) ;
	this->mState = wGdalRasterStateOpen ;
	return true ;
}
bool wGdalRasterU16::save(string filepath) 
{
	if( this->mState == wGdalRasterStateNone)
	{
		return false   ;
	}
	GDALDriver* driver = GetGDALDriverManager()->GetDriverByName("GTiff");
	GDALDataset* ds = driver->Create( filepath.c_str() , mXSize, mYSize , mNBand,GDT_UInt16 ,0) ;
	if( ds==0 )
	{
		return false  ;
	}
	for(int i = 0 ; i<mNBand ; ++ i )
	{
		unsigned short* ptr = mptrVec[i] ;
		CPLErr ioerror = ds->GetRasterBand(i+1)->RasterIO( GF_Write,
			0,0,mXSize,mYSize,
			ptr , 
			mXSize,mYSize,GDT_UInt16 , 
			0,0,0) ;
         if( ioerror != CE_None ){
            return false ;
        }
	}
	if( strlen( mProj ) > 1 && mTrans[1] > 0 )
	{
		ds->SetProjection( mProj ) ;
		ds->SetGeoTransform( mTrans ) ;
	}
	GDALClose(ds) ;
	return true ;
}
bool wGdalRasterU16::create(int nxsize,int nysize,int nband ) 
{
	if( this->mState != wGdalRasterStateNone)
	{
		return false ;
	}
	mXSize = nxsize ;
	mYSize = nysize ;
	mNBand = nband ;
	int asize = mXSize*mYSize ;
	for(int i = 0 ; i<mNBand ; ++ i )
	{
		unsigned short* ptr = new unsigned short[mXSize*mYSize] ;
		for(int it = 0 ; it<asize;++it) ptr[it] = 0.f ;
		mptrVec.push_back(ptr) ;
	}
	this->mState = wGdalRasterStateCreate ;
	return true ;
}


////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
//                                       I16
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
class wGdalRasterI16:public wGdalRaster
{
public:
	virtual float getValuef(int ix,int iy,int ib ) ;
	virtual float getValuef(int it ,int ib )  ;
	virtual int getValuei(int ix,int iy,int ib )  ;
	virtual int getValuei(int it , int ib  )  ;

	virtual void setValuef(int ix,int iy,int ib,float val)  ;
	virtual void setValuei(int ix,int iy,int ib,int val)    ;
	virtual void setValuef(int it,int ib,float val)  ;
	virtual void setValuei(int it,int ib,int val) ;

	virtual bool open(string filepath)  ;
	virtual bool save(string filepath)  ;
	virtual bool create(int nxsize,int nysize,int nband )  ;

	//new
	virtual void fill(int iband,int fillval) ;


	void release() ;
	virtual ~wGdalRasterI16() ;
protected:
	vector<short*> mptrVec ;
} ;


//new
void wGdalRasterI16::fill( int iband , int fillval )
{
	if( this->mState == wGdalRasterStateOpen ||  this->mState == wGdalRasterStateCreate )
	{
		if( iband < this->mptrVec.size() )
		{
			short* bandPtr = (short*)this->mptrVec[iband] ;
			int asize = this->mXSize * this->mYSize ;
			for(int it = 0 ; it < asize ; ++ it )
			{
				bandPtr[it] = fillval ;
			}
		}else
		{
			cout<<"wGdalRaster::fill error 1."<<endl ;
		}
	}else
	{
		cout<<"wGdalRaster::fill error 2."<<endl ;
	}
}


wGdalRasterI16::~wGdalRasterI16() 
{
	this->release() ;
}


void wGdalRasterI16::release()
{
	cout<<"release i16"<<endl ;
	this->mState = wGdalRasterStateNone ;
	for(int i = 0 ; i<mptrVec.size() ; ++ i )
	{
		if( mptrVec[i] )
		{
			delete[] mptrVec[i] ;
			mptrVec[i] = 0 ;
		}
	}
}
float wGdalRasterI16::getValuef(int ix,int iy,int ib ) 
{
	short* ptr = mptrVec[ib] ;
	return  (float) ptr[ix+iy*mXSize]  ;
}
float wGdalRasterI16::getValuef(int it ,int ib ) 
{
	short* ptr = mptrVec[ib] ;
	return  (float)ptr[it]  ;
}
int wGdalRasterI16::getValuei(int ix,int iy,int ib ) 
{
	short* ptr = mptrVec[ib] ;
	return (int)( ptr[ix+iy*mXSize] ) ;
}
int wGdalRasterI16::getValuei(int it , int ib  ) 
{
	short* ptr = mptrVec[ib] ;
	return (int)( ptr[it] ) ;
}
void wGdalRasterI16::setValuef(int ix,int iy,int ib,float val)  
{
	short*ptr = mptrVec[ib] ;
	ptr[ix+iy*mXSize] = val ;
}
void wGdalRasterI16::setValuei(int ix,int iy,int ib,int val)    
{
	short* ptr = mptrVec[ib] ;
	ptr[ix+iy*mXSize] = val ;
}
void wGdalRasterI16::setValuef(int it,int ib,float val)  
{
	short* ptr = mptrVec[ib] ;
	ptr[it] = val ;
}
void wGdalRasterI16::setValuei(int it,int ib,int val) 
{
	short* ptr = mptrVec[ib] ;
	ptr[it] = val ;
}

bool wGdalRasterI16::open(string filepath) 
{
	if( this->mState != wGdalRasterStateNone)
	{
		return false ;
	}
	GDALDataset* ds = (GDALDataset*)GDALOpen( filepath.c_str() , GA_ReadOnly ) ;
	if( ds==0 )
	{
		return false ;
	}

	strcpy( mProj , ds->GetProjectionRef() ) ;
	ds->GetGeoTransform( mTrans ) ;

	mXSize = ds->GetRasterXSize() ;
	mYSize = ds->GetRasterYSize() ;
	mNBand = ds->GetRasterCount() ;

	for(int i = 0 ; i<mNBand ; ++ i )
	{
		short* ptr = new short[mXSize*mYSize] ;
		CPLErr ioerror = ds->GetRasterBand(i+1)->RasterIO( GF_Read ,
			0,0,mXSize,mYSize,
			ptr , 
			mXSize,mYSize,GDT_Int16 , 
			0,0,0) ;
		mptrVec.push_back(ptr) ;
         if( ioerror != CE_None ){
            return false ;
        }
	}
	GDALClose(ds) ;
	this->mState = wGdalRasterStateOpen ;
	return true ;
}
bool wGdalRasterI16::save(string filepath) 
{
	if( this->mState == wGdalRasterStateNone)
	{
		return false   ;
	}
	GDALDriver* driver = GetGDALDriverManager()->GetDriverByName("GTiff");
	GDALDataset* ds = driver->Create( filepath.c_str() , mXSize, mYSize , mNBand,GDT_Int16 ,0) ;
	if( ds==0 )
	{
		return false  ;
	}
	for(int i = 0 ; i<mNBand ; ++ i )
	{
		short* ptr = mptrVec[i] ;
		CPLErr ioerror = ds->GetRasterBand(i+1)->RasterIO( GF_Write,
			0,0,mXSize,mYSize,
			ptr , 
			mXSize,mYSize,GDT_Int16 , 
			0,0,0) ;
         if( ioerror != CE_None ){
            return false ;
        }
	}
	if( strlen( mProj ) > 1 && mTrans[1] > 0 )
	{
		ds->SetProjection( mProj ) ;
		ds->SetGeoTransform( mTrans ) ;
	}
	GDALClose(ds) ;
	return true ;
}
bool wGdalRasterI16::create(int nxsize,int nysize,int nband ) 
{
	if( this->mState != wGdalRasterStateNone)
	{
		return false ;
	}
	mXSize = nxsize ;
	mYSize = nysize ;
	mNBand = nband ;
	int asize = mXSize*mYSize ;
	for(int i = 0 ; i<mNBand ; ++ i )
	{
		short* ptr = new short[mXSize*mYSize] ;
		memset(ptr , 0 , sizeof(short)*mXSize*mYSize ) ;
		mptrVec.push_back(ptr) ;
	}
	this->mState = wGdalRasterStateCreate ;
	return true ;
}



////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
//                                       I32
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
class wGdalRasterI32:public wGdalRaster
{
public:
	virtual float getValuef(int ix,int iy,int ib ) ;
	virtual float getValuef(int it ,int ib )  ;
	virtual int getValuei(int ix,int iy,int ib )  ;
	virtual int getValuei(int it , int ib  )  ;

	virtual void setValuef(int ix,int iy,int ib,float val)  ;
	virtual void setValuei(int ix,int iy,int ib,int val)    ;
	virtual void setValuef(int it,int ib,float val)  ;
	virtual void setValuei(int it,int ib,int val) ;

	virtual bool open(string filepath)  ;
	virtual bool save(string filepath)  ;
	virtual bool create(int nxsize,int nysize,int nband )  ;

	//new
	virtual void fill(int iband,int fillval) ;


	void release() ;
	virtual ~wGdalRasterI32() ;
protected:
	vector<int*> mptrVec ;
} ;


//new
void wGdalRasterI32::fill( int iband , int fillval )
{
	if( this->mState == wGdalRasterStateOpen ||  this->mState == wGdalRasterStateCreate )
	{
		if( iband < this->mptrVec.size() )
		{
			int* bandPtr = (int*)this->mptrVec[iband] ;
			int asize = this->mXSize * this->mYSize ;
			for(int it = 0 ; it < asize ; ++ it )
			{
				bandPtr[it] = fillval ;
			}
		}else
		{
			cout<<"wGdalRaster::fill error 1."<<endl ;
		}
	}else
	{
		cout<<"wGdalRaster::fill error 2."<<endl ;
	}
}


wGdalRasterI32::~wGdalRasterI32() 
{
	this->release() ;
}

void wGdalRasterI32::release()
{
	cout<<"release i32"<<endl ;
	this->mState = wGdalRasterStateNone ;
	for(int i = 0 ; i<mptrVec.size() ; ++ i )
	{
		if( mptrVec[i] )
		{
			delete[] mptrVec[i] ;
			mptrVec[i] = 0 ;
		}
	}
}
float wGdalRasterI32::getValuef(int ix,int iy,int ib ) 
{
	int* ptr = mptrVec[ib] ;
	return  (float) ptr[ix+iy*mXSize]  ;
}
float wGdalRasterI32::getValuef(int it ,int ib ) 
{
	int* ptr = mptrVec[ib] ;
	return  (float)ptr[it]  ;
}
int wGdalRasterI32::getValuei(int ix,int iy,int ib ) 
{
	int* ptr = mptrVec[ib] ;
	return  ptr[ix+iy*mXSize]   ;
}
int wGdalRasterI32::getValuei(int it , int ib  ) 
{
	int* ptr = mptrVec[ib] ;
	return   ptr[it]  ;
}
void wGdalRasterI32::setValuef(int ix,int iy,int ib,float val)  
{
	int*ptr = mptrVec[ib] ;
	ptr[ix+iy*mXSize] = val ;
}
void wGdalRasterI32::setValuei(int ix,int iy,int ib,int val)    
{
	int* ptr = mptrVec[ib] ;
	ptr[ix+iy*mXSize] = val ;
}
void wGdalRasterI32::setValuef(int it,int ib,float val)  
{
	int* ptr = mptrVec[ib] ;
	ptr[it] = val ;
}
void wGdalRasterI32::setValuei(int it,int ib,int val) 
{
	int* ptr = mptrVec[ib] ;
	ptr[it] = val ;
}

bool wGdalRasterI32::open(string filepath) 
{
	if( this->mState != wGdalRasterStateNone)
	{
		return false ;
	}
	GDALDataset* ds = (GDALDataset*)GDALOpen( filepath.c_str() , GA_ReadOnly ) ;
	if( ds==0 )
	{
		return false ;
	}

	strcpy( mProj , ds->GetProjectionRef() ) ;
	ds->GetGeoTransform( mTrans ) ;

	mXSize = ds->GetRasterXSize() ;
	mYSize = ds->GetRasterYSize() ;
	mNBand = ds->GetRasterCount() ;

	for(int i = 0 ; i<mNBand ; ++ i )
	{
		int* ptr = new int[mXSize*mYSize] ;
		CPLErr ioerror = ds->GetRasterBand(i+1)->RasterIO( GF_Read ,
			0,0,mXSize,mYSize,
			ptr , 
			mXSize,mYSize,GDT_Int32 , 
			0,0,0) ;
         if( ioerror != CE_None ){
            return false ;
        }
		mptrVec.push_back(ptr) ;
	}
	GDALClose(ds) ;
	this->mState = wGdalRasterStateOpen ;
	return true ;
}
bool wGdalRasterI32::save(string filepath) 
{
	if( this->mState == wGdalRasterStateNone)
	{
		return false   ;
	}
	GDALDriver* driver = GetGDALDriverManager()->GetDriverByName("GTiff");
	GDALDataset* ds = driver->Create( filepath.c_str() , mXSize, mYSize , mNBand,GDT_Int32 ,0) ;
	if( ds==0 )
	{
		return false  ;
	}
	for(int i = 0 ; i<mNBand ; ++ i )
	{
		int* ptr = mptrVec[i] ;
		CPLErr ioerror = ds->GetRasterBand(i+1)->RasterIO( GF_Write,
			0,0,mXSize,mYSize,
			ptr , 
			mXSize,mYSize,GDT_Int32 , 
			0,0,0) ;
         if( ioerror != CE_None ){
            return false ;
        }
	}
	if( strlen( mProj ) > 1 && mTrans[1] > 0 )
	{
		ds->SetProjection( mProj ) ;
		ds->SetGeoTransform( mTrans ) ;
	}
	GDALClose(ds) ;
	return true ;
}
bool wGdalRasterI32::create(int nxsize,int nysize,int nband ) 
{
	if( this->mState != wGdalRasterStateNone)
	{
		return false ;
	}
	mXSize = nxsize ;
	mYSize = nysize ;
	mNBand = nband ;
	int asize = mXSize*mYSize ;
	for(int i = 0 ; i<mNBand ; ++ i )
	{
		int* ptr = new int[mXSize*mYSize] ;
		memset(ptr,0,sizeof(int)*mXSize*mYSize) ;
		mptrVec.push_back(ptr) ;
	}
	this->mState = wGdalRasterStateCreate ;
	return true ;
}


#endif

